package com.rankeiot.core.data;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.rankeiot.core.util.StringUtil;
import com.rankeiot.core.util.castor.BooleanCastor;
import com.rankeiot.core.util.castor.DateCastor;
import com.rankeiot.core.util.castor.LongCastor;

import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
import java.util.Objects;
@JsonSerialize(using = StringValue.Serializer.class)
@JsonDeserialize(using = StringValue.DeSerializer.class)
public class StringValue implements CharSequence, Serializable {
    public static class Serializer extends JsonSerializer<StringValue>{
        @Override
        public void serialize(StringValue stringValue, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            jsonGenerator.writeString(stringValue.value);
        }
    }
    public static class DeSerializer extends JsonDeserializer<StringValue>{

        @Override
        public StringValue deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
            return new StringValue(jsonParser.getValueAsString());
        }
    }
    final String value;

    private StringValue(String v) {
        this.value = v;
    }
    public static StringValue of(String v){
        return new StringValue(v);
    }
    public String asString(String defaultValue) {
        return value == null ? defaultValue : value;
    }

    public String asString() {
        return value;
    }

    public Date asDate() {
        return DateCastor.instance.cast(value);
    }

    public Long asLong() {
        return LongCastor.instance.cast(value);
    }

    public Boolean asBoolean() {
        return BooleanCastor.instance.cast(value);
    }

    @Override
    public int length() {
        return value.length();
    }

    @Override
    public char charAt(int index) {
        return value.charAt(index);
    }
    public boolean isEmpty() {
        return StringUtil.isEmpty(value);
    }

    @Override
    public CharSequence subSequence(int start, int end) {
        return value.subSequence(start,end);
    }

    public boolean is(String v) {
        return Objects.equals(value, v);
    }

    public boolean is(Enum v) {
        return Objects.equals(value, v.name());
    }

    public boolean is(boolean v) {
        return asBoolean().booleanValue() == v;
    }

    public boolean is(Long v) {
        return Objects.equals(asLong(), v);
    }

    public int compare(Long v) {
        Long data=asLong();
        if (data == null || v == null) {
            return 0;
        }
        return data.compareTo(v);
    }

    public int compare(Date v) {
        Date date = asDate();
        if (date == null || v == null) {
            return 0;
        }
        return date.compareTo(v);
    }

    @Override
    public String toString() {
        return value;
    }
}
